package com.base.commom.http;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSON;


/**
 * 请求工具类
 * 
 * @author chenwei
 * @date 2018年3月28日 下午10:46:28
 */
public final class RequestUtil {
	
	
	/**
	 * httpClient get请求
	 * 
	 * @author chenwei
	 * @date 2018年3月30日 下午5:47:10
	 * @param url 请求url
	 * @param param 请求参数
	 * @param headParam 请求头
	 * @return
	 * @throws Exception
	 */
	public static ResponseEntity httpClientGet(String url, Map<String, String> param, Map<String, String> headParam)
			throws Exception {

		//创建httpclient对象
		CloseableHttpClient client = HttpClients.createDefault(); 
		//创建请求类型,并传入url
		CloseableHttpResponse response = null;
		
		try {
			//创建请求参数封装对象
			URIBuilder builder = new URIBuilder(url);
			if (param != null && !param.isEmpty()) {
				for (String key : param.keySet()) {
					builder.addParameter(key, param.get(key));
				}
			}
			// 创建请求类型,并传入url地址
			HttpGet httpGet = new HttpGet(builder.build());
			// 设置请求头
			if (headParam != null && !headParam.isEmpty()) {
				for (String key : headParam.keySet()) {
					httpGet.setHeader(key, headParam.get(key));
				}
			}
			System.out.println(httpGet);
			// 执行请求
			HttpResponse responseGet = client.execute(httpGet);
			// 获取响应状态码
			int statusCode = responseGet.getStatusLine().getStatusCode();
			// 获取响应参数内容
			String content = EntityUtils.toString(responseGet.getEntity(), Consts.UTF_8);
			ResponseEntity entity = new ResponseEntity();
			entity.setCode(statusCode);
			entity.setContent(content);
			return entity;
		} catch (Exception e) {
			throw e;
		}finally {
			closeClientAndResponse(client, response);
		}
	}
	
	/**
	 * httpClient post请求
	 * 
	 * @author chenwei
	 * @date 2018年3月30日 下午5:47:10
	 * @param url 请求url
	 * @param param 请求参数
	 * @param headParam 请求头
	 * @return
	 * @throws Exception
	 */
	public static ResponseEntity httpClientPost(String url, Map<String, String> param, Map<String, String> headParam)
			throws Exception {
		//创建httpclient对象
		CloseableHttpClient client = HttpClients.createDefault(); 
		//创建请求类型,并传入url
		CloseableHttpResponse response = null;
		try {
			//创建请求类型,并传入url
			HttpPost httpPost = new HttpPost(url);
			//设置请求参数
			// 设置请求头
			if (headParam != null && !headParam.isEmpty()) {
				for (String key : headParam.keySet()) {
					httpPost.setHeader(key, headParam.get(key));
				}
			}
			//设置请求参数
			httpPost.setEntity(new StringEntity(JSON.toJSONString(param), ContentType.APPLICATION_FORM_URLENCODED));
			//执行请求返回响应数据
			response = client.execute(httpPost);
			//获取响应状态码
			int statusCode = response.getStatusLine().getStatusCode();
			//获取响应数据内容
			String content = EntityUtils.toString(response.getEntity(),Consts.UTF_8);
			ResponseEntity entity = new ResponseEntity();
			entity.setCode(statusCode);
			entity.setContent(content);
			return entity;
		} catch (Exception e) {
			throw e;
		}finally {
			closeClientAndResponse(client, response);
		}
	}
	/**
	 * post请求
	 * 
	 * @author chenwei
	 * @date 2018年11月29日 下午5:32:21
	 * @param url
	 * @param param
	 * @param json
	 * @return
	 * @throws Exception
	 */
	public static ResponseEntity httpClientPost(String url, Map<String, String> param,boolean json)
			throws Exception {
		
		//创建httpclient对象
		CloseableHttpClient client = HttpClients.createDefault(); 
		//创建请求类型,并传入url
		CloseableHttpResponse response = null;
		try {
			HttpPost httpPost = new HttpPost(url);
			//设置请求参数
			/** 定义List集合封装表单请求参数 */
			if(json) {
				StringEntity se = new StringEntity(JSON.toJSONString(param));
				se.setContentType("application/json");
				se.setContentEncoding(new BasicHeader(HTTP.CONTENT_ENCODING,"UTF-8"));
				httpPost.setEntity(se);
			}else {
				List<NameValuePair> nvpLists = new ArrayList<NameValuePair>();
				if(nvpLists!=null && !nvpLists.isEmpty()) {
					for (Map.Entry<String, String> entry : param.entrySet()){
						/** 设置请求参数 */
						nvpLists.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
					}
				}
				UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(nvpLists, Consts.UTF_8);
				httpPost.setEntity(uefEntity);
			}
			//执行请求返回响应数据
			System.out.println(httpPost);
			response = client.execute(httpPost);
			//获取响应状态码
			int statusCode = response.getStatusLine().getStatusCode();
			//获取响应数据内容
			String content = EntityUtils.toString(response.getEntity(),Consts.UTF_8);
			ResponseEntity entity = new ResponseEntity();
			entity.setCode(statusCode);
			entity.setContent(content);
			return entity;
		} catch (Exception e) {
			throw e;
		}finally {
			closeClientAndResponse(client, response);
		}
	}
	/**
	 * httpClient post请求
	 * 
	 * @author chenwei
	 * @date 2018年7月5日 上午12:04:44
	 * @param url
	 * @param params
	 * @param headParam
	 * @param json
	 * @return
	 * @throws Exception
	 */
	public static InputStream httpClientPost2(String url, Map<String, String> params, Map<String, String> headParam,boolean json)
			throws Exception {
		
		//创建httpclient对象
		CloseableHttpClient client = HttpClients.createDefault(); 
		CloseableHttpResponse responsePost = null;
		try {
			//创建请求类型,并传入url
			HttpPost httpPost = new HttpPost(url);
			//设置请求参数
			// 设置请求头
			if (headParam != null && !headParam.isEmpty()) {
				for (String key : headParam.keySet()) {
					httpPost.addHeader(key, headParam.get(key));
				}
			}
			/** 定义List集合封装表单请求参数 */
			if(json) {
				StringEntity se = new StringEntity(JSON.toJSONString(params));
				se.setContentType("application/json");
				se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,"UTF-8"));
				httpPost.setEntity(se);
			}else {
				List<NameValuePair> nvpLists = new ArrayList<NameValuePair>();
				if(nvpLists!=null && !nvpLists.isEmpty()) {
					for (Map.Entry<String, String> entry : params.entrySet()){
						/** 设置请求参数 */
						nvpLists.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
					}
				}
				UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(nvpLists, Consts.UTF_8);
				httpPost.setEntity(uefEntity);
			}
			/** 设置请求参数 */
			//执行请求返回响应数据
			responsePost = client.execute(httpPost);
			HttpEntity entity = responsePost.getEntity();
			if(entity!=null) {
				InputStream is = entity.getContent();
				return is;
			}
			//获取响应状态码
			return null;
		} catch (Exception e) {
			throw e;
		}finally {
			closeClientAndResponse(client, responsePost);
		}
	}
	
	/**
	 * httpClient post请求
	 * 
	 * @author chenwei
	 * @date 2018年7月5日 上午12:04:44
	 * @param url
	 * @param params
	 * @param headParam
	 * @param json
	 * @return
	 * @throws Exception
	 */
	public static InputStream httpClientPost3(String url, Map<String, String> params, Map<String, String> headParam,boolean json)
			throws Exception {
		
		//创建httpclient对象
		CloseableHttpClient client = HttpClients.createDefault(); 
		//创建请求类型,并传入url
		CloseableHttpResponse response = null;
		try {
			//创建请求类型,并传入url
			HttpPost httpPost = new HttpPost(url);
			//设置请求参数
			// 设置请求头
			if (headParam != null && !headParam.isEmpty()) {
				for (String key : headParam.keySet()) {
					httpPost.addHeader(key, headParam.get(key));
				}
			}
			/** 定义List集合封装表单请求参数 */
			if(json) {
				StringEntity se = new StringEntity(JSON.toJSONString(params));
				se.setContentType("application/json");
				se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,"UTF-8"));
				httpPost.setEntity(se);
			}else {
				List<NameValuePair> nvpLists = new ArrayList<NameValuePair>();
				if(nvpLists!=null && !nvpLists.isEmpty()) {
					for (Map.Entry<String, String> entry : params.entrySet()){
						/** 设置请求参数 */
						nvpLists.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
					}
				}
				UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(nvpLists, Consts.UTF_8);
				httpPost.setEntity(uefEntity);
			}
			/** 设置请求参数 */
			//执行请求返回响应数据
			HttpResponse responsePost = client.execute(httpPost);
			HttpEntity entity = responsePost.getEntity();
			if(entity!=null) {
				InputStream is = entity.getContent();
				return is;
			}
			//获取响应状态码
			return null;
		} catch (Exception e) {
			throw e;
		}finally {
			closeClientAndResponse(client, response);
		}
	}
	
	/**
	 * 利用HttpClient发送PUT请求
	 * @param url 请求地址
	 * @param params 请求参数
	 * @return 响应实体
	 * @throws Exception 
	 */
	public static ResponseEntity  httpClientPut(String url, Map<String, String> params, boolean json) throws Exception{
		/** 定义可关闭的HttpClient客户端对象 */
		CloseableHttpClient httpClient = HttpClients.createDefault(); 
		/** 定义可关闭的响应对象 */
		CloseableHttpResponse response = null;
		try{
			/** 创建URI */
			URI uri = new URIBuilder(url).build();
			/** 创建HttpPut请求对象 */
			HttpPut httpPut = new HttpPut(uri);
			/** 判断是否需要设置请求参数 */
			if (params != null && params.size() > 0){
				
				if (json){
					httpPut.setEntity(new StringEntity(JSON.toJSONString(params),
							ContentType.APPLICATION_JSON));
				}else{
					/** 定义List集合封装表单请求参数 */
					List<NameValuePair> nvpLists = new ArrayList<>();
					for (Map.Entry<String, String> entry : params.entrySet()){
						/** 设置请求参数 */
						nvpLists.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
					}
					/** 设置请求参数 */
					httpPut.setEntity(new UrlEncodedFormEntity(nvpLists, Consts.UTF_8));
				}
			}
			/** 执行请求，得到响应对象 */
			response = httpClient.execute(httpPut);
			/** 获取响应数据 */
			String content = (response.getEntity() != null) 
					? EntityUtils.toString(response.getEntity(), Consts.UTF_8) : null;
			/** 返回响应实体 */
			ResponseEntity entity = new ResponseEntity();
			entity.setCode(response.getStatusLine().getStatusCode());
			entity.setContent(content);
			return entity;
		}catch(Exception ex){
			throw ex;
		}finally{
			closeClientAndResponse(httpClient, response);
		}
	}
	/**
	 * 
	 * DELETE请求
	 * 
	 * @author chenwei
	 * @date 2018年11月29日 下午5:32:41
	 * @param url 请求地址
	 * @param params 请求参数
	 * @return
	 * @throws Exception
	 */
	public static ResponseEntity httpClientDelete(String url, Map<String, String> params) throws Exception{
		/** 定义可关闭的HttpClient客户端对象 */
		CloseableHttpClient httpClient = HttpClients.createDefault(); 
		/** 定义可关闭的响应对象 */
		CloseableHttpResponse response = null;
		try {
			HttpDelete httpDelete = new HttpDelete(url);
			/** 判断请求参数Map集合 */
			if (params != null && !params.isEmpty()){
				for (String key: params.keySet()) {
					httpDelete.addHeader(key, params.get(key));
				}
			}
			response = httpClient.execute(httpDelete);
			/** 获取响应数据 */
			String content = (response.getEntity() != null) 
					? EntityUtils.toString(response.getEntity(), Consts.UTF_8) : null;
			/** 返回响应实体 */
			ResponseEntity responseEntity = new ResponseEntity();
			responseEntity.setCode(response.getStatusLine().getStatusCode());
			responseEntity.setContent(content);
			return responseEntity;
		} catch (Exception e) {
			throw e;
		}finally {
			closeClientAndResponse(httpClient, response);
		}
	}
	
	/**
	 * 关闭client和response资源
	 * 
	 * @author chenwei
	 * @date 2018年11月29日 下午5:45:24
	 * @param client
	 * @param response
	 */
	private static void closeClientAndResponse(CloseableHttpClient client,CloseableHttpResponse response) {
		try {
			if(client != null) {
				client.close();
			}
			if(response != null) {
				response.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
//	public static void main(String[] args) throws Exception {
//		String content = httpClientDelete("http://localhost:9200/goods", null).getContent();
//		System.out.println(content);
//	}
}
